package cn.stylefeng.guns.modular.api;

import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.alipay.AliPayApi;
import cn.stylefeng.guns.alipay.AliPayApiConfig;
import cn.stylefeng.guns.alipay.AliPayApiConfigKit;
import cn.stylefeng.guns.config.redis.redis.util.Redishandler0;
import cn.stylefeng.guns.core.PayModeType;
import cn.stylefeng.guns.core.RecoverConst;
import cn.stylefeng.guns.modular.business.entity.UserGrade;
import cn.stylefeng.guns.modular.business.service.UserGradeService;
import cn.stylefeng.guns.pay.entity.WxPayBean;
import cn.stylefeng.guns.pay.kit.IpKit;
import cn.stylefeng.guns.pay.vo.AjaxResult;
import cn.stylefeng.guns.sys.core.util.IdGen;
import cn.stylefeng.guns.wxpay.WxPayApi;
import cn.stylefeng.guns.wxpay.constant.enums.SignType;
import cn.stylefeng.guns.wxpay.constant.enums.TradeType;
import cn.stylefeng.guns.wxpay.kit.WxPayKit;
import cn.stylefeng.guns.wxpay.model.UnifiedOrderModel;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import cn.stylefeng.guns.pay.entity.AliPayBean;
import cn.stylefeng.guns.pay.utils.StringUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Map;

/**
 * 用户等级
 *
 * @Author pzp .
 * @Date 2019/8/29:59
 */

@Controller
@RequestMapping("/gunsApi/userGrade")
@Slf4j
public class UserGradeApi extends BaseController{

    @Autowired
    private Redishandler0 redishandler0;
    @Autowired
    private UserGradeService userGradeService;

    @Autowired
    WxPayBean wxPayBean;

    @Autowired
    private AliPayBean aliPayBean;

    @Value("${file.serverIP}")
    private String serverIP;

    @ApiOperation("用户等级及等级明细")
    @GetMapping("/detail")
    @ResponseBody
    public ResponseData detail(Long userId) {
        return ResponseData.success(userGradeService.detail(userId));
    }

    @ApiOperation("升级用户等级")
    @PostMapping("/update")
    public ResponseData update(HttpServletRequest request, @RequestParam(required = false) String openId, @RequestParam Long userId, @RequestParam Integer gradeLevel, @RequestParam Integer payMode, HttpServletResponse response) {
        String gradestr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "", gradeLevel.toString());
        if (StringUtils.isEmpty(gradestr)) {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null;
            try {
                out = response.getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            out.write(JSONObject.toJSONString(ResponseData.error("等级数据提交错误")));
            out.flush();
            out.close();
            return ResponseData.error("等级数据提交错误");
        }
        UserGrade userGrade = JSONObject.parseObject(gradestr, UserGrade.class);
        BigDecimal money = userGrade.getFee();
        String orderNo = IdGen.getOrderNoByDate(24);
        if (payMode.equals(PayModeType.AMOUNT.getCode())) {
            if (userGradeService.update(userId, orderNo, gradeLevel.toString(), money, payMode)) {
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = null;
                try {
                    out = response.getWriter();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                out.write(JSONObject.toJSONString(ResponseData.success("升级成功")));
                out.flush();
                out.close();
                return ResponseData.success("升级成功");
            }
        } else if(payMode.equals(PayModeType.ALIPAY.getCode())){
            if (userGradeService.update(userId, orderNo, gradeLevel.toString(), money, payMode)) {
                AliPayApiConfig aliPayApiConfig = AliPayApiConfig.New()
                        .setAppId(aliPayBean.getAppId())
                        .setAliPayPublicKey(aliPayBean.getPublicKey())
                        .setCharset("UTF-8")
                        .setPrivateKey(aliPayBean.getPrivateKey())
                        .setServiceUrl(aliPayBean.getServerUrl())
                        .setSignType("RSA2")
                        .build();
                AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
                String body = "胖蚂蚁回收升级费用";
                String subject = "胖蚂蚁回收升级费用";
                String totalAmount = money + "";
                String passbackParams = money + "";
                //String returnUrl = aliPayBean.getDomain() + "/gunsApi/pay/up-zfb-notify";
                String notifyUrl = aliPayBean.getDomain() + "/gunsApi/pay/up-zfb-notify";

                AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
                model.setBody(body);
                model.setSubject(subject);
                model.setTotalAmount(money.toString());
                model.setPassbackParams(passbackParams);
                log.info("wap outTradeNo>" + orderNo);
                model.setOutTradeNo(orderNo);
                model.setProductCode("QUICK_WAP_PAY");
                try {
                    AliPayApi.wapPay(response, model, "", notifyUrl);
//            AliPayApi.wapPayByOutputStream(response, model, returnUrl, notifyUrl);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return ResponseData.success();
            }
        } else {//微信
            // openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
            if (StrUtil.isEmpty(openId)) {
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = null;
                try {
                    out = response.getWriter();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                out.write(JSONObject.toJSONString(ResponseData.error("openId错误")));
                out.flush();
                out.close();
                return ResponseData.error("openId错误");
            }
            if (userGradeService.update(userId, orderNo, gradeLevel.toString(), money, payMode)) {
                Map<String, String> params = UnifiedOrderModel
                        .builder()
                        .appid(wxPayBean.getAppId())
                        .mch_id(wxPayBean.getMchId())
                        .nonce_str(WxPayKit.generateStr())
                        .body("胖蚂蚁回收升级会员等级费用")
                        .attach("胖蚂蚁回收升级会员等级费用")
                        .openid(openId)
                        .out_trade_no(orderNo)
                        .total_fee(money.multiply(new BigDecimal(100)).toString())
                        .spbill_create_ip(serverIP)
                        .notify_url(wxPayBean.getDomain().concat("/gunsApi/pay/up-wx-notify"))
                        .trade_type(TradeType.JSAPI.getTradeType())
                        .build()
                        .creatSign(wxPayBean.getPartnerKey(), SignType.HMACSHA256);
                //money.multiply(new BigDecimal(100)).toString()

                String xmlResult = WxPayApi.pushOrder(false,params);
                log.info(xmlResult);

                Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
                String return_code = resultMap.get("return_code");
                String return_msg = resultMap.get("return_msg");
                String result_code = resultMap.get("result_code");

                if (!WxPayKit.codeIsOK(return_code) || !WxPayKit.codeIsOK(result_code)) {
                    response.setCharacterEncoding("utf-8");
                    response.setContentType("application/json; charset=utf-8");
                    PrintWriter out = null;
                    try {
                        out = response.getWriter();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    out.write(JSONObject.toJSONString(ResponseData.error(return_msg)));
                    out.flush();
                    out.close();
                    return ResponseData.error(return_msg);
                }

                // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
                String prepay_id = resultMap.get("prepay_id");
                Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepay_id, wxPayBean.getAppId(), wxPayBean.getPartnerKey(),SignType.HMACSHA256);

                String jsonStr = JSON.toJSONString(packageParams);
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = null;
                try {
                    out = response.getWriter();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                out.write(JSONObject.toJSONString(ResponseData.success(jsonStr)));
                out.flush();
                out.close();
                return ResponseData.success(jsonStr);
            }
        }
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.write(JSONObject.toJSONString(ResponseData.error("处理错误")));
        out.flush();
        out.close();
        return ResponseData.error("处理错误");
    }
}
